package com.chuangjiangx.member.score.ddd.query;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.member.score.ddd.dal.condition.*;
import com.chuangjiangx.member.score.ddd.dal.dto.*;
import com.chuangjiangx.member.score.ddd.dal.mapper.ScoreGiftRuleCountDalMapper;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrSourceTerminal;
import com.chuangjiangx.member.score.ddd.query.dto.MemberScoreGiftListDTO;
import com.chuangjiangx.member.score.ddd.query.dto.ScoreGiftRuleCountByGiftDTO;
import com.chuangjiangx.member.score.ddd.query.dto.ScoreGiftRuleCountByStoreDTO;
import com.chuangjiangx.member.score.ddd.query.dto.ScoreGiftRuleCountByTimeDTO;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 积分兑换统计查询
 */
@Component
public class MbrScoreGiftRuleCountQuery {


    private final ScoreGiftRuleCountDalMapper scoreGiftRuleCountDalMapper;

    @Autowired
    public MbrScoreGiftRuleCountQuery(ScoreGiftRuleCountDalMapper scoreGiftRuleCountDalMapper) {
        this.scoreGiftRuleCountDalMapper = scoreGiftRuleCountDalMapper;

    }

    /**
     * 根据时间统计top10
     *
     * @param condition 根据时间查询条件
     */
    private List<ScoreGiftRuleCountByTimeDTO> countTop10ByTime(
            ScoreGiftRuleByTimeCondition condition) {
        List<ScoreGiftRuleCountByTime> list;
        RowBounds rb = new RowBounds(0, 10);
        if (condition.getStartTime() != null && condition.getEndTime() != null) {
            Long time = condition.getEndTime().getTime() - condition.getStartTime().getTime();
            if (time <= 24 * 60 * 60 * 1000) {
                list = scoreGiftRuleCountDalMapper.countByTimeWithHour(condition, rb);
            } else {
                list = scoreGiftRuleCountDalMapper.countByTime(condition, rb);
            }
        } else {
            list = scoreGiftRuleCountDalMapper.countByTime(condition, rb);
        }
        return CJBeanUtils.convertCollection(list, ScoreGiftRuleCountByTimeDTO.class);
    }

    /**
     * 根据时间统计top10 -- 商户权限
     *
     * @param condition 根据时间查询条件
     */
    public List<ScoreGiftRuleCountByTimeDTO> countTop10ByTimeForMerchant(
            ScoreGiftRuleByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setStoreId(null);
        return countTop10ByTime(condition);
    }

    /**
     * 根据时间统计top10 -- 门店权限
     *
     * @param condition 根据时间查询条件
     */
    public List<ScoreGiftRuleCountByTimeDTO> countTop10ByTimeForStore(
            ScoreGiftRuleByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getStoreId(), "门店id不能为空");
        return countTop10ByTime(condition);
    }

    /**
     * 按门店统计top10
     *
     * @param condition 查询条件
     * @return 返回门店统计top10
     */
    public List<ScoreGiftRuleCountByStoreDTO> countTop10ByStoreForMerchant(
            ScoreGiftRuleCountByStoreCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        RowBounds rb = new RowBounds(0, 10);
        List<ScoreGiftRuleCountChartByStore> list = scoreGiftRuleCountDalMapper.countChartByStore(condition, rb);
        return CJBeanUtils.convertCollection(list, ScoreGiftRuleCountByStoreDTO.class, (source, target) -> {
            if (source.getStoreName() == null) {
                target.setStoreName(source.getUserName());
            }
        });
    }

    /**
     * 按门店统计兑换量列表
     *
     * @param condition 查询条件
     * @return 返回门店统计的列表
     */
    public PagingResult<ScoreGiftRuleCountByStoreDTO> countByStoreForMerchant(
            MemberScoreGiftCountListByStoreCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        RowBounds rb = new RowBounds(condition.offset(), condition.limit());
        ScoreGiftRuleCountByStoreCondition condition2 = new ScoreGiftRuleCountByStoreCondition();
        BeanUtils.copyProperties(condition, condition2);
        List<ScoreGiftRuleCountListByStore> list = scoreGiftRuleCountDalMapper.countListByStore(condition2, rb);
        PageInfo<ScoreGiftRuleCountListByStore> pageInfo = new PageInfo<>(list);
        List<ScoreGiftRuleCountByStoreDTO> dtoList = CJBeanUtils.convertCollection(
                list, ScoreGiftRuleCountByStoreDTO.class, (source, target) -> {
                    if (source.getStoreName() == null) {
                        target.setStoreName(source.getUserName());
                    }
                });
        return new PagingResult<>(pageInfo.getTotal(), dtoList);
    }

    /**
     * 根据兑换规则统计兑换量
     *
     * @param condition 查询条件
     * @return 返回兑换统计
     */
    private PagingResult<ScoreGiftRuleCountByGiftDTO> countByGift(ScoreGiftRuleCountByGiftCondition condition) {
        RowBounds rb = new RowBounds(condition.offset(), condition.limit());
        List<ScoreGiftRuleCountByGift> list = scoreGiftRuleCountDalMapper.countByGift(condition, rb);
        PageInfo<ScoreGiftRuleCountByGift> pageInfo = new PageInfo<>(list);
        List<ScoreGiftRuleCountByGiftDTO> dtoList = CJBeanUtils.convertCollection(
                list, ScoreGiftRuleCountByGiftDTO.class);
        return new PagingResult<>(pageInfo.getTotal(), dtoList);
    }

    /**
     * 根据兑换规则统计TOP10兑换量 - 商户权限
     *
     * @param condition 查询条件
     * @return 返回兑换统计
     */
    public List<ScoreGiftRuleCountByGiftDTO> countTop10ByGiftForMerchant(
            ScoreGiftRuleCountByGiftCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setPageNumber(1);
        condition.setPageSize(10);
        PagingResult<ScoreGiftRuleCountByGiftDTO> pr = countByGift(condition);
        return pr.getItems();
    }

    /**
     * 根据兑换规则统计TOP10兑换量 - 门店权限
     *
     * @param condition 查询条件
     * @return 返回兑换统计
     */
    public List<ScoreGiftRuleCountByGiftDTO> countTop10ByGiftForStore(ScoreGiftRuleCountByGiftCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getStoreId(), "门店id不能为空");
        condition.setPageNumber(1);
        condition.setPageSize(10);
        PagingResult<ScoreGiftRuleCountByGiftDTO> pr = countByGift(condition);
        return pr.getItems();
    }

    /**
     * 根据兑换规则统计兑换量 - 商户权限
     *
     * @param condition 查询条件
     * @return 返回兑换统计
     */
    public PagingResult<ScoreGiftRuleCountByGiftDTO> countByGiftForMerchant(
            ScoreGiftRuleCountByGiftCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setStoreId(null);
        return countByGift(condition);
    }

    /**
     * 根据兑换规则统计兑换量 - 门店权限
     *
     * @param condition 查询条件
     * @return 返回兑换统计
     */
    public PagingResult<ScoreGiftRuleCountByGiftDTO> countByGiftForStore(
            ScoreGiftRuleCountByGiftCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getStoreId(), "门店id不能为空");
        return countByGift(condition);
    }


    /**
     * 根据时间查询兑换明细
     *
     * @param condition 查询条件
     * @return 返回兑换明细数据
     */
    private PagingResult<MemberScoreGiftListDTO> queryDetailByTime(MemberScoreGiftByTimeCondition condition) {
        RowBounds rb = new RowBounds(condition.offset(), condition.limit());
        List<MemberScoreGiftList> list = scoreGiftRuleCountDalMapper.queryDetailByTime(condition, rb);
        PageInfo<MemberScoreGiftList> pageInfo = new PageInfo<>(list);
        List<MemberScoreGiftListDTO> dtoList = CJBeanUtils.convertCollection(list,
                MemberScoreGiftListDTO.class, (source, target) -> {
                    target.setTerminalTypeName(MbrSourceTerminal.getSourceTerminal(source.getTerminalType()).name);//杨括修改
                });
        return new PagingResult<>(pageInfo.getTotal(), dtoList);
    }

    /**
     * 根据时间查询兑换明细 -- 商户权限
     *
     * @param condition 查询条件
     * @return 返回兑换明细数据
     */
    public PagingResult<MemberScoreGiftListDTO> queryByTimeForMerchant(MemberScoreGiftByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setStoreId(null);
        return queryDetailByTime(condition);
    }

    /**
     * 根据时间查询兑换明细 -- 门店权限
     *
     * @param condition 查询条件
     * @return 返回兑换明细数据
     */
    public PagingResult<MemberScoreGiftListDTO> queryByTimeForStore(MemberScoreGiftByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getStoreId(), "门店id不能为空");
        return queryDetailByTime(condition);
    }

    /**
     * 根据积分兑换统计明细 -- 门店权限
     *
     * @param condition 查询条件
     * @return 返回兑换明细数据
     */
    public PagingResult<MemberScoreGiftListDTO> queryByTimeForStoreGift(MemberScoreGiftByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        Assert.notNull(condition.getStoreId(), "门店id不能为空");
        condition.setEndTime(addDate(condition.getEndTime()));
        return queryDetailByTime(condition);
    }

    /**
     * 根据门店查询兑换明细 -- 商户权限
     *
     * @param condition 查询条件
     * @return 返回兑换明细数据
     */
    public PagingResult<MemberScoreGiftListDTO> queryByStoreForMerchant(MemberScoreGiftByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        return queryDetailByTime(condition);
    }

    /**
     * 积分兑换 - 商户
     *
     * @param condition
     * @return
     */
    public PagingResult<MemberScoreGiftListDTO> queryByStoreGiftForMerchant(MemberScoreGiftByTimeCondition condition) {
        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
        condition.setEndTime(addDate(condition.getEndTime()));
        return queryDetailByTime(condition);
    }

    public Date addDate(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        cld.add(Calendar.DATE, 1);
        return cld.getTime();
    }
}
